/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Server.domain;

import static Server.domain.BomberManGameServer.MAX_CLIENTS;
import Server.domain.threads.BomberManClientThread;
import Server.domain.threads.Translator;
import Server.gui.BomberManServerGUI;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

/**
 *
 * @author user
 */
public class BomberManGameServer {

    
     public static final int MAX_CLIENTS = 4;
    private BomberManServerGUI bmGui;
    private PlayerList pList;
    private int no_clients;
    private int clientId;
    private int udpPort;
    private DatagramPacket packet;
    private DatagramSocket socket;

    public void setSocket(DatagramSocket socket) {
        this.socket = socket;
    }

   

    public int getUdpPort() {
        return udpPort;
    }
    private boolean running;
    private ArrayList<BomberManClientThread> clients;
    private String tcpPort;
    
    
    
    
    public BomberManGameServer(int udpPort, BomberManServerGUI bmGui) {
        this.udpPort = udpPort;
        this.bmGui = bmGui;
        clients = new ArrayList<>();
    }
    
    
    public void start() {
        running = true;

        try {
            ServerSocket serverSocket = new ServerSocket(udpPort);

            while (running) {
                appendEventMessage("Server waiting for Clients on port " + udpPort + ".");
                Socket socket = serverSocket.accept();

                if (!running) {
                    break;
                }

                if (no_clients < MAX_CLIENTS) {
                    BomberManClientThread clThread = new BomberManClientThread(this, socket, clientId);
                    clients.add(clThread);
                    clThread.start();
                    clThread.writeMsg(clThread.getUsername() + "Has connected to the server.");
                    pList.add(new Player(clThread.getUsername()));
                    no_clients++;
                    clientId++;
                } else {
                    bmGui.appendEventMessage("SERVER FULL: Client tried to connect");
                    
                }
            }

            try {
                serverSocket.close();

                for (int i = 0; i < clients.size(); ++i) {
                    BomberManClientThread clThread = clients.get(i);
                    clThread.close();
                }
            } catch (Exception e) {
                appendEventMessage("Exception closing the server and clients: " + e);
            }
        } catch (IOException e) {
            appendEventMessage("Exception on new ServerSocket: " + e);
        }
    }
    
     

    //Method to handle server stop
    public void stop() {
        running = false;

        appendEventMessage("The Game server is stopping...");

        try {
            new Socket("localhost", udpPort);
        } catch (Exception e) {
        }
    }

    //Method for removing a clientThread when client disconnects
    public synchronized void removeClient(int clientId) {
        for (int i = 0; i < clients.size(); ++i) {
            BomberManClientThread clientThread = clients.get(i);

            if (clientThread.getClientId() == clientId) {
                clients.remove(i);
                appendEventMessage("Client " + clientId + "has disconnected.");
                no_clients--;
                System.out.println(clientId);
                return;
            }
        }
    }
    
    
    //Method for appending messages to the textArea
    public void appendEventMessage(String eventString) {
        bmGui.appendEventMessage(eventString);
    }
    
       public boolean isRunning() {
        return running;
    }
       
        public void setRunning(boolean running) {
        this.running = running;
    }
        
        public void receivePacket() throws IOException
	{
		//receive message from client
		byte[] buf = new byte[256];
		packet = new DatagramPacket(buf, buf.length);
		socket.receive(packet);
		
		//translate message in a thread
		String message = new String(packet.getData(), 0, packet.getLength());
		Translator translator = new Translator(pList,message);
		translator.start();
	}
	public void sendPacket() throws IOException
	{
		//create message of all xs and ys of all players
		byte[] buf = pList.toString().getBytes();
		
		//send the message to the client to the given address and port
		InetAddress address = packet.getAddress();
		int port = packet.getPort();
		packet = new DatagramPacket(buf, buf.length, address, port);
		socket.send(packet);
	}
}
